'''
@file:    find_qrcodes_follow.py
@company: Hiwonder
@author:  CuZn
@date:    2023-08-25
@description: 二维码识别，并将识别后的数据发送给 开发板（STM32等）
        # K210视觉模块 会将识别到的方框数据和识别信息 通过串口 发送给 开发板（STM32等）

'''

#载入相关模块
import sensor, image, time, lcd
from hiwonder import hw_uart, hw_led , fill_light
import binascii
import time

#创建LED控制对象
led = hw_led()
#创建补光灯控制对象
f_led = fill_light()

#定义串口对象
serial = hw_uart()


##################################### send_func begin #####################################

#CRC校验参数，不可修改，否则数据通讯会出错
crc8_table = [
    0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
    157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
    35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
    190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
    70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
    219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
    101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
    248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
    140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
    17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
    175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
    50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
    202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
    87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
    233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
    116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
]

#CRC校验函数
def checksum_crc8(data):
    # 校验
    check = 0
    for b in data:
        check = crc8_table[check ^ b]
    return check & 0x00FF

#功能号
class FuncTag:
    START = 0
    FIND_QRCODES  = 3


#字符串转int
def str_2_int(data_str):
    bb = binascii.hexlify(data_str)
    bb = str(bb)[2:-1]
    int_h = int(bb[0])*16
    int_l = int(bb[1],16)
    return int_h+int_l


def send_data(x,y,w,h,msg):
    '''
    0xAA  0x55  功能号  数据长度  data  CRC
    '''
    START_1 = 0xAA
    START_2 = 0x55
    FUNC_num = FuncTag.FIND_QRCODES #功能编号
    Length = 0  #数据长度
    crc = 0 #校验位
    data = [] #数据组

    #参数都为0
    if x==0 and y==0 and w==0 and h ==0:
        pass
    else:
        #x(小端模式)
        low = x & 0xFF #低位
        high = x >> 8& 0xFF #高位
        data.append(low)
        data.append(high)

        #y(小端模式)
        low = y & 0xFF #低位
        high = y >> 8& 0xFF #高位
        data.append(low)
        data.append(high)

        #w(小端模式)
        low = w & 0xFF #低位
        high = w >> 8& 0xFF #高位
        data.append(low)
        data.append(high)

        #h(小端模式)
        low = h & 0xFF #低位
        high = h >> 8& 0xFF #高位
        data.append(low)
        data.append(high)

    #msg
    if msg != None:
        for i in range(len(msg)):
            msg_int = str_2_int(msg[i])
            data.append(msg_int)

    Length += len(data)
    send_buf = [FUNC_num,Length]
    for i in range(len(data)):
        send_buf.append(data[i])

    #进行CRC运算
    crc = checksum_crc8(send_buf)

    send_buf.insert(0,START_1) #插入协议头1
    send_buf.insert(1,START_2) #插入协议头2
    send_buf.append(crc) #加入CRC校验码

    #print(send_buf) #打印数据
    serial.send_bytearray(send_buf) #发送数据


##################################### send_func end #####################################

#定义发送数据
send_x = 0
send_y = 0
send_w = 0
send_h = 0
send_msg = ""



#初始化LCD
lcd.init()
#以下是初始化传感器
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 100)
#帧率时钟
clock = time.clock()

def recv_serial():
    bt = serial.rec_bytes()
    #bt = bt.strip()
    print("recv_serial_data:", bt)
    #data = bt.decode('utf-8')
    #print("data:", data)
    if bt == b'1\r\n':
        print("i receive mega 2560 msg")

program_process_count = 0
#loop
while(True):
    #用于计算帧率的函数，这里表示开始计时
    clock.tick()
    #从传感器捕获一张图像
    img = sensor.snapshot()
    #遍历图像中找到的二维码
    try:
        recv_serial()
        time.sleep(0.01)
        program_process_count = program_process_count + 1
        print("program_process_count:", program_process_count)
        if program_process_count == 1:
            for code in img.find_qrcodes():
                #print("code:", code)
                #绘制矩形和识别出的信息
                img.draw_rectangle(code.rect(), color = 127, thickness=3)
                img.draw_string(0, 0, code.payload(), color=(255, 0, 0), scale=8.5)
                #将方框数据与消息赋值
                send_x = code.x()
                send_y = code.y()
                send_w = code.w()
                send_h = code.h()
                send_msg = code.payload()

            # 当消息标志不为 '' 时，发送数据
            if send_msg != "":
                #发送数据
                send_data(send_x,send_y,send_w,send_h,send_msg)
                send_msg = ""   # 清空消息变量
                for i in range(2):
                    f_led.fill_onoff(1)
                    time.sleep(0.01)
                    f_led.fill_onoff(0)
                    time.sleep(0.01)

        if program_process_count == 2:
            print("section2")

        elif program_process_count == 3:
            print("section3")
            program_process_count = 0

        else:
            print("nothing")
    except:
        print("nothing to do")

    #显示在LCD上
    lcd.display(img)
    #print(clock.fps()) #打印帧率




